Correct problems with earlier fix for bug #480065
authorKristian Rietveld <kris@gtk.org>
Mon, 21 Dec 2009 21:33:59 +0000 (22:33 +0100)
committerKristian Rietveld <kris@gtk.org>
Mon, 21 Dec 2009 21:42:15 +0000 (22:42 +0100)
Initialize event_last_[xy] to out of range coordinates and also update
these values in enter and leave notify.  Fix up calls to
update_prelight() from size allocate.  Unconditionally doing these calls
caused problems with hover selection.  Now we only do this call when
the "width before the expander column" has changed.  (Which might be
awkward, but it is the best heuristic I could come up with so far).

gtk/gtktreeprivate.h
gtk/gtktreeview.c

index dd0cf8d2a9bef7d7f22cb36277d6e73d85e88607..c44d61813db9027b7d9acc5e1a24b3caacec4737 100644 (file)
@@ -175,6 +175,8 @@ struct _GtkTreeViewPrivate
   GList *column_drag_info;
   GtkTreeViewColumnReorder *cur_reorder;
 
+  gint prev_width_before_expander;
+
   /* Interactive Header reordering */
   GdkWindow *drag_window;
   GdkWindow *drag_highlight_window;
index 560f35c963fb8c7601f10f47946e50421983c4ba..1a606772f848900a30ee1438217af2bdb11b2d9c 100644 (file)
@@ -1378,6 +1378,9 @@ gtk_tree_view_init (GtkTreeView *tree_view)
 
   tree_view->priv->last_button_x = -1;
   tree_view->priv->last_button_y = -1;
+
+  tree_view->priv->event_last_x = -10000;
+  tree_view->priv->event_last_y = -10000;
 }
 
 \f
@@ -2052,6 +2055,25 @@ gtk_tree_view_size_request (GtkWidget      *widget,
     }
 }
 
+static int
+gtk_tree_view_calculate_width_before_expander (GtkTreeView *tree_view)
+{
+  int width = 0;
+  GList *list;
+  gboolean rtl;
+
+  rtl = (gtk_widget_get_direction (GTK_WIDGET (tree_view)) == GTK_TEXT_DIR_RTL);
+  for (list = (rtl ? g_list_last (tree_view->priv->columns) : g_list_first (tree_view->priv->columns));
+       list->data != tree_view->priv->expander_column;
+       list = (rtl ? list->prev : list->next))
+    {
+      GtkTreeViewColumn *column = list->data;
+
+      width += column->width;
+    }
+
+  return width;
+}
 
 static void
 invalidate_column (GtkTreeView       *tree_view,
@@ -2438,14 +2460,30 @@ gtk_tree_view_size_allocate (GtkWidget     *widget,
            }
        }
 
+      if (width_changed && tree_view->priv->expander_column)
+        {
+          /* Might seem awkward, but is the best heuristic I could come up
+           * with.  Only if the width of the columns before the expander
+           * changes, we will update the prelight status.  It is this
+           * width that makes the expander move vertically.  Always updating
+           * prelight status causes trouble with hover selections.
+           */
+          gint width_before_expander;
+
+          width_before_expander = gtk_tree_view_calculate_width_before_expander (tree_view);
+
+          if (tree_view->priv->prev_width_before_expander
+              != width_before_expander)
+              update_prelight (tree_view,
+                               -tree_view->priv->event_last_x,
+                               -tree_view->priv->event_last_y);
+
+          tree_view->priv->prev_width_before_expander = width_before_expander;
+        }
+
       /* This little hack only works if we have an LTR locale, and no column has the  */
       if (width_changed)
        {
-          if (tree_view->priv->tree)
-            update_prelight (tree_view,
-                             tree_view->priv->event_last_x,
-                             tree_view->priv->event_last_y);
-
          if (gtk_widget_get_direction (GTK_WIDGET (tree_view)) == GTK_TEXT_DIR_LTR &&
              ! has_expand_column)
            invalidate_last_column (tree_view);
@@ -3264,6 +3302,16 @@ prelight_or_select (GtkTreeView *tree_view,
     do_prelight (tree_view, tree, node, x, y);
 }
 
+static void
+ensure_unprelighted (GtkTreeView *tree_view)
+{
+  do_prelight (tree_view,
+              NULL, NULL,
+              -1000, -1000); /* coords not possibly over an arrow */
+
+  g_assert (tree_view->priv->prelight_node == NULL);
+}
+
 static void
 update_prelight (GtkTreeView *tree_view,
                  gint         x,
@@ -3273,6 +3321,12 @@ update_prelight (GtkTreeView *tree_view,
   GtkRBTree *tree;
   GtkRBNode *node;
 
+  if (x == -10000)
+    {
+      ensure_unprelighted (tree_view);
+      return;
+    }
+
   new_y = TREE_WINDOW_Y_TO_RBTREE_Y (tree_view, y);
   if (new_y < 0)
     new_y = 0;
@@ -3284,16 +3338,6 @@ update_prelight (GtkTreeView *tree_view,
     prelight_or_select (tree_view, tree, node, x, y);
 }
 
-static void
-ensure_unprelighted (GtkTreeView *tree_view)
-{
-  do_prelight (tree_view,
-              NULL, NULL,
-              -1000, -1000); /* coords not possibly over an arrow */
-
-  g_assert (tree_view->priv->prelight_node == NULL);
-}
-
 
 
 
@@ -5507,6 +5551,9 @@ gtk_tree_view_enter_notify (GtkWidget        *widget,
     new_y = 0;
   _gtk_rbtree_find_offset (tree_view->priv->tree, new_y, &tree, &node);
 
+  tree_view->priv->event_last_x = event->x;
+  tree_view->priv->event_last_y = event->y;
+
   if ((tree_view->priv->button_pressed_node == NULL) ||
       (tree_view->priv->button_pressed_node == node))
     prelight_or_select (tree_view, tree, node, event->x, event->y);
@@ -5531,6 +5578,9 @@ gtk_tree_view_leave_notify (GtkWidget        *widget,
                                    tree_view->priv->prelight_node,
                                    NULL);
 
+  tree_view->priv->event_last_x = -10000;
+  tree_view->priv->event_last_y = -10000;
+
   prelight_or_select (tree_view,
                      NULL, NULL,
                      -1000, -1000); /* coords not possibly over an arrow */